/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package session.stateless;

import com.sun.mail.imap.protocol.MailboxInfo;
import entity.EventEntity;
import entity.MessageEntity;
import entity.OwnerEntity;
import entity.InboxEntity;
import entity.MessageActionEntity;
import entity.MessageFolderEntity;
import entity.OutboxEntity;
import entity.TrashEntity;
import exception.ExistException;
import java.security.acl.Owner;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateful;
import javax.ejb.LocalBean;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author KohLi
 */
@Stateful
@LocalBean
public class MessageSessionBean {

    @PersistenceContext
    private EntityManager entityManager;
    //@EJB
    //private StakeholderSessionBean stakeholderSession;
    @EJB
    private SystemMessagesBean systemMessages;

    public void createMailbox(OwnerEntity newUser) {
        //ty owner = new  OwnerEntity();

        InboxEntity inbox = new InboxEntity();
        entityManager.persist(inbox);
        OutboxEntity outbox = new OutboxEntity();
        entityManager.persist(outbox);
        TrashEntity trash = new TrashEntity();
        entityManager.persist(trash);

        MessageFolderEntity mailbox = new MessageFolderEntity();
        mailbox.setInbox(inbox);
        mailbox.setOutbox(outbox);
        mailbox.setTrash(trash);
        entityManager.persist(mailbox);

        OwnerEntity owner = new OwnerEntity();
        owner.setName(newUser.getName());
        owner.setStaff(newUser.isStaff());
        owner.setTourist(newUser.isTourist());
        owner.setStakeholder(newUser.isStakeholder());
        owner.setMailbox(mailbox);
        entityManager.persist(owner);


    }

    public void saveMessage(OwnerEntity reciver, OwnerEntity sender, MessageEntity msg, InboxEntity userMessage) throws ExistException {
        //create message
        System.out.println("at session message:" + msg.getMessage() + msg.getSubject());

        System.out.println("creating message action for the message");
        MessageActionEntity action = new MessageActionEntity(false, false, false, false, true);
        entityManager.persist(action);

        System.out.println("creating new message body");
        MessageEntity message = new MessageEntity();
        message.setMessage(msg.getMessage());
        Date d = new Date();
        message.setMsgDate(d);
        message.setMsgType("MSG");
        message.setSubject(msg.getSubject());
        message.setSender(msg.getSender());
        message.setReceiver(msg.getReceiver());
        message.setAction(action);
        entityManager.persist(message);

        //create action for the message



        //check whether sender exist & get the mailbox
        Long reciverMailboxId = checkSystemUser(reciver.getName());
        Long senderMailBoxId = checkSystemUser(sender.getName());

        //if (reciverMailboxId != null && senderMailBoxId != null) {
        //get the neccessary inbox / outbox  
        MessageFolderEntity mailbox = entityManager.find(MessageFolderEntity.class, reciverMailboxId);
        Long inboxId = mailbox.getInbox().getId();
        System.out.println("inbox Id" + inboxId);
        InboxEntity inbox = entityManager.find(InboxEntity.class, inboxId);
        inbox.getInboxMessage().add(message);
        //inbox.setAction(action);
        entityManager.persist(inbox);
        mailbox.setInbox(inbox);
        entityManager.persist(mailbox);

        mailbox = entityManager.find(MessageFolderEntity.class, senderMailBoxId);
        Long outboxId = mailbox.getOutbox().getId();
        System.out.println("outbox Id" + outboxId);
        OutboxEntity outbox = entityManager.find(OutboxEntity.class, outboxId);
        outbox.getOutboxMessage().add(message);
        entityManager.persist(outbox);




    }

    public void updateMessageAction(MessageEntity msg) {
        MessageEntity message = entityManager.find(MessageEntity.class, msg.getId());
        MessageActionEntity action = message.getAction();
        action.setSee(msg.getAction().isSee());
        entityManager.persist(action);

    }

    public void deleteMessage(MessageEntity msg, String ownerName) throws ExistException {

        //

        Long mailboxId = checkSystemUser(ownerName);
        MessageFolderEntity mailbox = entityManager.find(MessageFolderEntity.class, mailboxId);
        System.out.println("getting the message...");
        if (mailboxId == null) {
            throw new ExistException("INVALID MAILBOX");
        } else {
            /*/need to valid whether message exist in mailbox
            mailbox.getInbox().getInboxMessage().contains(msg);
            System.out.println("message inbox?" + mailbox.getInbox().getInboxMessage().contains(msg));
            
            mailbox.getInbox().getInboxMessage().remove(msg);
            entityManager.persist(mailbox);
             */
            //get the message

            MessageEntity message = entityManager.find(MessageEntity.class, msg.getId());
            //set the action to delete to true 
            //check whether can it be move from db
            if (message != null) {
                MessageActionEntity action = message.getAction();
                action.setKeep(false);
                //check if can move to db
                if (action.isDeleteFromMailbox()) {
                    action.setDeleteFromDataBase(true);
                } else {
                    action.setDeleteFromMailbox(true);
                    Date d = new Date();
                    message.setDeletedDate(d);

                }
                entityManager.persist(action);
                entityManager.persist(message);

                //move the mail to trash
                //find whether the person has trash box
                TrashEntity bin = mailbox.getTrash();
                if (bin == null) {
                    bin = new TrashEntity();
                    bin.getTrashMessage().add(message);
                    entityManager.persist(bin);

                    mailbox.setTrash(bin);
                    entityManager.merge(mailbox);

                } else {//i had a trash bin

                    bin = entityManager.find(TrashEntity.class, mailbox.getTrash().getId());
                    bin.getTrashMessage().add(message);

                    entityManager.persist(mailbox);

                }
                //removing relationship of message in trashbin.
                mailbox.getInbox().getInboxMessage().contains(msg);
                System.out.println("message inbox?" + mailbox.getInbox().getInboxMessage().contains(msg));
                List<MessageEntity> messageList = new ArrayList<MessageEntity>();

                for (int i = 0; i < (mailbox.getInbox().getInboxMessage().size()); i++) {

                    if (mailbox.getInbox().getInboxMessage().get(i).getSubject() != msg.getSubject()) {
                        messageList.add(mailbox.getInbox().getInboxMessage().get(i));
                    }

                }

                mailbox.getInbox().setInboxMessage(messageList);
                entityManager.persist(mailbox);
            } else {
                throw new ExistException("SOMETHING_WRONG");
            }

        }
    }

    public void deleteMessageFromOutbox(MessageEntity msg, String ownerName) throws ExistException {

        //

        Long mailboxId = checkSystemUser(ownerName);
        MessageFolderEntity mailbox = entityManager.find(MessageFolderEntity.class, mailboxId);
        System.out.println("getting the message from outbox...");
        if (mailboxId == null) {
            throw new ExistException("INVALID_MAILBOX");
        } else {
            /*/need to valid whether message exist in mailbox
            mailbox.getInbox().getInboxMessage().contains(msg);
            System.out.println("message inbox?" + mailbox.getInbox().getInboxMessage().contains(msg));
            
            mailbox.getInbox().getInboxMessage().remove(msg);
            entityManager.persist(mailbox);
             */
            //get the message

            MessageEntity message = entityManager.find(MessageEntity.class, msg.getId());
            //set the action to delete to true 
            //check whether can it be move from db
            if (message != null) {
                MessageActionEntity action = message.getAction();
                action.setKeep(false);
                //check if can move to db
                if (action.isDeleteFromMailbox()) {
                    action.setDeleteFromDataBase(true);
                } else {
                    action.setDeleteFromMailbox(true);
                    Date d = new Date();
                    message.setDeletedDate(d);

                }
                entityManager.persist(action);
                //move the mail to trash
                //find whether the person has trash box

                TrashEntity bin = mailbox.getTrash();
                if (bin == null) {
                    System.out.println("creating a new trash bin...");
                    bin = new TrashEntity();
                    bin.getTrashMessage().add(message);
                    entityManager.persist(bin);

                    mailbox.setTrash(bin);
                    entityManager.merge(mailbox);

                } else {
                    bin = entityManager.find(TrashEntity.class, mailbox.getTrash().getId());
                    bin.getTrashMessage().add(message);

                    entityManager.persist(mailbox);

                }
                mailbox.getOutbox().getOutboxMessage().contains(msg);

                //removing r/s in outbox.
                List<MessageEntity> messageList = new ArrayList<MessageEntity>();

                for (int i = 0; i < (mailbox.getOutbox().getOutboxMessage().size()); i++) {

                    if (mailbox.getOutbox().getOutboxMessage().get(i).getSubject() != msg.getSubject()) {
                        messageList.add(mailbox.getOutbox().getOutboxMessage().get(i));
                    }

                }

                mailbox.getOutbox().setOutboxMessage(messageList);
                entityManager.persist(mailbox);
            } else {
                throw new ExistException("SOMETHING_WRONG");
            }

        }
    }

    public void createAccnouncement(MessageEntity message, String sender) {
        //get all mailbox based on stakeholder user
        Query q = getEntityManager().createQuery("SELECT user FROM Owner user");
        List<Long> stakeholderInboxMailboxId = new ArrayList<Long>();
        List<OwnerEntity> ownerList = q.getResultList();
        for (int i = 0; i < ownerList.size(); i++) {
            if (ownerList.get(i).isStakeholder()) {
                //retrieve the mailbox of stakeholder
                System.out.println("getting stakeholder inbox");
                stakeholderInboxMailboxId.add(ownerList.get(i).getMailbox().getInbox().getId());
            }
        }
        System.out.println("creating action");
        //create action
        MessageActionEntity action = new MessageActionEntity(false, false, false, false, true);
        entityManager.persist(action);
        System.out.println("creating announcement");
        //creating new announcement
        MessageEntity announcement = new MessageEntity();
        Date d = new Date();
        announcement.setMsgDate(d);
        announcement.setSender(sender);
        announcement.setMessage(message.getMessage());
        announcement.setMsgType("ANNOUNCEMENT");
        announcement.setSubject(message.getSubject());
        announcement.setAction(action);
        entityManager.persist(announcement);
        InboxEntity inbox = new InboxEntity();
        for (int i = 0; i < stakeholderInboxMailboxId.size(); i++) {
            //retrieve their inboxid
            inbox = entityManager.find(InboxEntity.class, stakeholderInboxMailboxId.get(i));
            //crea
            inbox.getInboxMessage().add(announcement);
            entityManager.persist(inbox);
        }

        System.out.println("finish adding announcement");
    }

    public List<MessageEntity> getMyInbox(String owner) {

        Long mailboxId = checkSystemUser(owner);
        System.out.println("what is my mailboxId? \t" + mailboxId);
        MessageFolderEntity mailbox = entityManager.find(MessageFolderEntity.class, mailboxId);

        //reverse the list order from latest
        List<MessageEntity> tempMsgList = new ArrayList<MessageEntity>();
        tempMsgList = mailbox.getInbox().getInboxMessage();
        System.out.println("what is templist size" + tempMsgList.size());

        List<MessageEntity> messageList = new ArrayList<MessageEntity>();
        //reverse the messagelist (show newest first)
        if (tempMsgList.size() > 1) {
            MessageEntity msg = new MessageEntity();
            for (int i = (tempMsgList.size() - 1); i > -1; i--) {
                msg = tempMsgList.get(i);
                messageList.add(msg);
            }
        } else {
            return tempMsgList;
        }
        return messageList;
    }

    public List<MessageEntity> getMyOutbox(String owner) {

        Long mailboxId = checkSystemUser(owner);
        System.out.println("what is my mailboxId? \t" + mailboxId);
        MessageFolderEntity mailbox = entityManager.find(MessageFolderEntity.class, mailboxId);

        List<MessageEntity> tempMsgList = new ArrayList<MessageEntity>();
        tempMsgList = mailbox.getOutbox().getOutboxMessage();

        List<MessageEntity> messageList = new ArrayList<MessageEntity>();

        if (tempMsgList.size() > 1) {
            MessageEntity msg = new MessageEntity();
            for (int i = (tempMsgList.size() - 1); i > -1; i--) {
                msg = tempMsgList.get(i);
                messageList.add(msg);
            }
        } else {
            return tempMsgList;
        }

        return messageList;

    }

    public List<MessageEntity> getDeleteMessageDb() {
        List<MessageEntity> msgList = new ArrayList<MessageEntity>();
        Query q = entityManager.createQuery("SELECT msg FROM Message msg");
        List<MessageEntity> allMsgList = new ArrayList<MessageEntity>();
        allMsgList = q.getResultList();
        Date today = new Date();
        Calendar cal = new GregorianCalendar();
        cal.setTime(today);
        cal.add(Calendar.DAY_OF_MONTH, -30);
        //get 30days ago
        Date today30 = cal.getTime();

        if (!allMsgList.isEmpty()) {
            for (int i = 0; i < allMsgList.size(); i++) {
                if (allMsgList.get(i).getAction().isDeleteFromDataBase()) {
                    if (allMsgList.get(i).getDeletedDate().before(today30)) {
                        msgList.add(allMsgList.get(i));
                    }
                }
            }
        }

        return msgList;
    }

    
    public List<MessageEntity> getMyTrash(String owner) {

        Long mailboxId = checkSystemUser(owner);
        System.out.println("what is my mailboxId? \t" + mailboxId);
        MessageFolderEntity mailbox = entityManager.find(MessageFolderEntity.class, mailboxId);
        List<MessageEntity> tempMsgList = new ArrayList<MessageEntity>();
        tempMsgList = mailbox.getTrash().getTrashMessage();
        List<MessageEntity> messageList = new ArrayList<MessageEntity>();
        Date today = new Date();
        Calendar cal = new GregorianCalendar();

        cal.setTime(today);

        cal.add(Calendar.DAY_OF_MONTH, -30);
        Date today30 = cal.getTime();


        if (tempMsgList.size() > 1) {
            MessageEntity msg = new MessageEntity();
            for (int i = (tempMsgList.size() - 1); i > -1; i--) {
                msg = tempMsgList.get(i);
                //compare date is it after 30days!
                if (msg.getDeletedDate().after(today30)) {
                    messageList.add(msg);
                }

            }
        } else {
            if (tempMsgList.get(0).getDeletedDate().after(today30)) {
                tempMsgList.clear();
                return tempMsgList;
            } else {
                return tempMsgList;
            }
        }

        return messageList;
    }

    public MessageEntity getMessage(Long messageId) {
        MessageEntity msg = entityManager.find(MessageEntity.class, messageId);

        return msg;
    }
//public List< getMyMessage()

    private void createUser(OwnerEntity systemUser, MessageFolderEntity folder, MessageActionEntity action) {
        //check owner

        OwnerEntity user = new OwnerEntity();
        user.setName(systemUser.getName());
        user.setStaff(systemUser.isStaff());
        user.setStakeholder(systemUser.isStakeholder());
        user.setTourist(systemUser.isTourist());
        user.setMailbox(folder);
        //user.setInbox(inbox);
        user.setAction(action);
        entityManager.persist(user);

    }

    public List<OwnerEntity> getAllOwner() {
        Query q = getEntityManager().createQuery("SELECT user FROM Owner user");
        List<OwnerEntity> ownerList = q.getResultList();
        return ownerList;
    }

    public InboxEntity getUserInboxByUser(OwnerEntity user) {
        Query q = entityManager.createQuery("SELECT um FROM UserMessage um");
        //q.setParameter("subject", user.);
        return (InboxEntity) q.getSingleResult();

    }

    private Long checkSystemUser(String owner) {
        Long mailboxId = null;
        OwnerEntity user = new OwnerEntity();
        Query q = getEntityManager().createQuery("SELECT user FROM Owner user WHERE user.name =:name");
        q.setParameter("name", owner);

        if (!q.getResultList().isEmpty()) {
            user = (OwnerEntity) q.getSingleResult();
            mailboxId = user.getMailbox().getId();
        }
        return mailboxId;
        //return user;
    }

    public boolean deleteMessageFromTrash(MessageEntity[] msg, String ownerName) throws ExistException {

        List<MessageEntity> msgList = new ArrayList<MessageEntity>();

        Long mailboxId = checkSystemUser(ownerName);
        MessageFolderEntity mailbox = entityManager.find(MessageFolderEntity.class, mailboxId);
        System.out.println(
                "getting the message from outbox...");

        if (mailboxId
                == null) {
            throw new ExistException("INVALID MAILBOX");
        } else {
            TrashEntity trash = entityManager.find(TrashEntity.class, mailbox.getTrash().getId());
            msgList = trash.getTrashMessage();
            for (int i = 0; i < msg.length; i++) {
                MessageEntity message = entityManager.find(MessageEntity.class, msg[i].getId());
                if (message != null) {
                    for (int j = 0; j < trash.getTrashMessage().size(); j++) {
                        if (trash.getTrashMessage().get(j).getId() == msg[i].getId()) {
                        }
                    }
                }
            }
            entityManager.flush();
            return true;
        }
    }

    public void deleteMessageFromDB(MessageEntity deleteMsg) throws ExistException {
        //get the list of owner inbox;
        List<OwnerEntity> ownerList = getAllOwner();
        MessageEntity notToBeDeletedMsg = new MessageEntity();
        List<MessageEntity> newTrashBin = new ArrayList<MessageEntity>();
        MessageFolderEntity mailbox = new MessageFolderEntity();
        TrashEntity trashbin = new TrashEntity();
        List<MessageEntity> currentTrashBinMsgList = new ArrayList<MessageEntity>();
        
        for (int i = 0; i < ownerList.size(); i++) {
            mailbox = ownerList.get(i).getMailbox();
            trashbin = mailbox.getTrash();
            currentTrashBinMsgList = trashbin.getTrashMessage();
            System.out.println("trashbin size" + trashbin.getTrashMessage().size());
            System.out.println("message to be deleted id\t" + deleteMsg.getId());
            if (currentTrashBinMsgList.get(i).getId() != deleteMsg.getId()) {
                System.out.println("the trashmessage id \t" + currentTrashBinMsgList.get(i).getId());
                newTrashBin.add(currentTrashBinMsgList.get(i));
            }

            trashbin.setTrashMessage(newTrashBin);
            entityManager.persist(trashbin);
            mailbox.setTrash(trashbin);
            entityManager.persist(mailbox);

        }
    }

    
    public void replyMessage(MessageEntity msg) throws ExistException{
        
                //create message
        System.out.println("at session message:" + msg.getMessage() + msg.getSubject());

        System.out.println("creating message action for the message");
        MessageActionEntity action = new MessageActionEntity(false, false, false, false, true);
        entityManager.persist(action);

        System.out.println("creating new message body");
        MessageEntity message = new MessageEntity();
        message.setMessage(msg.getMessage());
        Date d = new Date();
        message.setMsgDate(d);
        message.setMsgType("MSG");
        message.setSubject(msg.getSubject());
        message.setSender(msg.getSender());
        message.setReceiver(msg.getReceiver());
        message.setAction(action);
        entityManager.persist(message);

        //create action for the message

        //check whether sender exist & get the mailbox
        Long reciverMailboxId = checkSystemUser(message.getReceiver());
        Long senderMailBoxId = checkSystemUser(message.getSender());

        //if (reciverMailboxId != null && senderMailBoxId != null) {
        //get the neccessary inbox / outbox  
        MessageFolderEntity mailbox = entityManager.find(MessageFolderEntity.class, reciverMailboxId);
        Long inboxId = mailbox.getInbox().getId();
        System.out.println("inbox Id" + inboxId);
        InboxEntity inbox = entityManager.find(InboxEntity.class, inboxId);
        inbox.getInboxMessage().add(message);
        //inbox.setAction(action);
        entityManager.persist(inbox);
        mailbox.setInbox(inbox);
        entityManager.persist(mailbox);

        mailbox = entityManager.find(MessageFolderEntity.class, senderMailBoxId);
        Long outboxId = mailbox.getOutbox().getId();
        System.out.println("outbox Id" + outboxId);
        OutboxEntity outbox = entityManager.find(OutboxEntity.class, outboxId);
        outbox.getOutboxMessage().add(message);
        entityManager.persist(outbox);
        
        
    }
    public OwnerEntity getSystemUser(OwnerEntity owner) {
        OwnerEntity user = new OwnerEntity();
        return user;
    }

    /**
     * @return the entityManager
     */
    public EntityManager getEntityManager() {
        return entityManager;
    }

    /**
     * @param entityManager the entityManager to set
     */
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    /**
     * @return the systemMessages
     */
    public SystemMessagesBean getSystemMessages() {
        return systemMessages;
    }

    /**
     * @param systemMessages the systemMessages to set
     */
    public void setSystemMessages(SystemMessagesBean systemMessages) {
        this.systemMessages = systemMessages;
    }
}
